package com.eroly.util.cacheUpdate;

import com.eroly.util.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.*;
import java.util.concurrent.TimeUnit;

/**
 * @author zyp
 */
@Component
public class RedisCache {
    private static Logger logger = LoggerFactory.getLogger(RedisCache.class);
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    /**
     * 获取对应key的value Object类型
     *
     * @param key 键
     * @return
     */
    public Object getRedisValue(String key) {
        final String keyf = key;
        return get(keyf);
    }

    public Object get(final String keyf) {
        logger.info("--------RedisCache.get start----");
        logger.info("--------Redis key:{}----", keyf);
        Object object = redisTemplate.execute(new RedisCallback<Object>() {
            @Override
            public Object doInRedis(RedisConnection connection) throws DataAccessException {
                byte[] key = keyf.getBytes();
                byte[] value = connection.get(key);
                if (value == null) {
                    return null;
                }
                return toObject(value);
            }
        });
        logger.info("--------RedisCache.get end----");
        return object;
    }

    /**
     * key对应的value放入缓存
     *
     * @param key
     * @param value
     */
    public void putObject(String key, Object value) {
        if (StringUtil.isNotEmpty(key) && null != value) {
            put(key, value);
        }
    }

    /**
     * key对应的value放入缓存
     */
    public void put(String key, Object value) {
        logger.info("--------RedisCache.put start----");
        logger.info("--------Redis key:{}----", key);
        final String keyf = key;
        final Object valuef = value;
        final long liveTime = 5 * 60;
        redisTemplate.execute(new RedisCallback<Long>() {
            @Override
            public Long doInRedis(RedisConnection connection) throws DataAccessException {
                byte[] keyb = keyf.getBytes();
                byte[] valueb = toByteArray(valuef);
                connection.set(keyb, valueb);
                if (liveTime > 0) {
                    connection.expire(keyb, liveTime);
                }
                return 1L;
            }
        });
        logger.info("--------RedisCache.put end----");
    }

    /**
     * 对象转换为二进制数组
     *
     * @param obj
     * @return
     */
    private byte[] toByteArray(Object obj) {
        byte[] bytes = null;
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream oos = null;
        try {
            oos = new ObjectOutputStream(bos);
            oos.writeObject(obj);
            oos.flush();
            bytes = bos.toByteArray();
        } catch (IOException ex) {
            logger.error(ex.getMessage(),ex);
        }finally {
            try {
                if (oos != null){
                    oos.close();
                }
                bos.close();
            } catch (IOException e) {
                logger.error(e.getMessage(),e);
            }
        }
        return bytes;
    }

    /**
     * 二进制数组转化为object对象
     *
     * @param bytes
     * @return
     */
    private Object toObject(byte[] bytes) {
        Object obj = null;
        try {
            ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
            ObjectInputStream ois = new ObjectInputStream(bis);
            obj = ois.readObject();
            ois.close();
            bis.close();
        } catch (IOException ex) {
            logger.error(ex.getMessage(),ex);
        } catch (ClassNotFoundException ex) {
            logger.error(ex.getMessage(),ex);
        }
        return obj;
    }

    /**
     * 清空缓存
     */
    public void clear() {
        logger.info("clear key");
        redisTemplate.execute(new RedisCallback<String>() {
            @Override
            public String doInRedis(RedisConnection connection) throws DataAccessException {
                connection.flushDb();
                return "ok";
            }
        });
    }

    public RedisTemplate<String, Object> getRedisTemplate() {
        return redisTemplate;
    }

    public void setRedisTemplate(RedisTemplate<String, Object> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

}